package com.ux.tween
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.utils.Dictionary;

	/**
	 * @author winnie
	 */	
	public class TweenCore
	{
		
		private var dicDuration : Dictionary = new Dictionary( true );
		private var dicEff : Dictionary = new Dictionary( true );
		private var dicDivide : Dictionary = new Dictionary( true );
		private var dicTime : Dictionary = new Dictionary( true );
		private var dicDestinationTime : Dictionary = new Dictionary( true );
		private var dicInit : Dictionary = new Dictionary( true );
		
		private var yoyoCount : Number = 0;
		
		/**
		 * @param _target
		 * @param _duration
		 * @param _eff
		 */
		public function TweenCore( _target:DisplayObject, _duration:Number, _eff:Object )
		{
			dicDuration[ _target ] = _duration;
			dicEff[ _target ] = _eff;
			dicTime[ _target ] = 0;
			dicDivide[ _target ] = new Object();
			dicInit[ _target ] = new Object();
			
			yoyoCount = _eff.yoyoCount;
			
			// stage 에 없으면 실행하지 않는다.
			if( _target.stage == null )
			{
				trace(" ==> TweenCore TweenCore : Stop tween because not had stage." );
				return;
			}
			else
			{
				dicDestinationTime[ _target ] = Math.floor( _target.stage.frameRate * _duration );
			}
			
			for( var val : String in _eff )
			{
				if( _target.hasOwnProperty( val ) )
				{
					dicDivide[ _target ][val] = ( _eff[ val ]-_target[ val ] ) / dicDestinationTime[ _target ];
					dicInit[ _target ][val] = _target[val];
				}
				else dicInit[ _target ][val] = _eff[ val ];
			}
			
			_target.addEventListener(Event.ENTER_FRAME, onUpdate );
			
			// onStart
			if( dicEff[ _target ].onStart ) dicEff[ _target ].onStart();
		}
		
		
		private function onUpdate( e:Event ):void
		{
			var _target : DisplayObject = e.currentTarget as DisplayObject;
			

			for( var val : String in dicDivide[ _target ] )
			{
				if( _target.hasOwnProperty( val ) )
				{
					_target[val] += dicDivide[ _target ][ val ];
				}
			}
			
			// onUpdate
			if( dicEff[ _target ].onUpdate ) dicEff[ _target ].onUpdate();
			
			dicTime[ _target ]++;
			
			if( dicTime[ _target ] == dicDestinationTime[ _target ] )
			{
				_target.removeEventListener( Event.ENTER_FRAME, onUpdate );
				
				// onComplete
				if( dicEff[ _target ].onComplete ) dicEff[ _target ].onComplete();
				
				// 목적지 강제 셋팅
				for( var valDestination : String in dicEff[ _target ] )
				{
					if( _target.hasOwnProperty( valDestination ) )
						_target[valDestination] = dicEff[ _target ][ valDestination ];
				}
				
				// yoyo setting
				if( yoyoCount && yoyoCount > 0 )
				{
					dicInit[ _target ].yoyoCount--;
					TweenUx.to( _target, dicDuration[ _target ] , dicInit[ _target ] );
				}
				else if( yoyoCount && yoyoCount == -1 )
				{
					TweenUx.to( _target, dicDuration[ _target ] , dicInit[ _target ] );
				}
				else
				{
					killTween( _target );
				}
			}
		}
		
		/**
		 * @param _target 트윈 kill
		 */		
		public function killTween( _target:DisplayObject ):void
		{
			_target.removeEventListener( Event.ENTER_FRAME, onUpdate );
			
			delete dicDuration[ _target ];
			delete dicEff[ _target ];
			delete dicDivide[ _target ];
			delete dicTime[ _target ];
			delete dicDestinationTime[ _target ];
			delete dicInit[ _target ];
		}
	}
}



